﻿using Game15;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;

[TestClass()]
public class GameFifteenTest
{
    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void CellNumberToDirectionTest()
    {
        GameFifteen.Matrix = new string[,]
        {
            { "4","2","3","7" },
            { " ","6","11","8" },
            { "9","2","5","12" },
            { "1","10","15","13" }
        };
        GameFifteen.EmptyCellRow = 1;
        GameFifteen.EmptyCellColumn = 0;
        int cellNumber = 9;
        bool expected = true;
        bool actual;
        int actualDirection;
        int expectedDirection = 2;
        actual = GameFifteen_Accessor.CellNumberToDirection(cellNumber, out actualDirection);
        Assert.AreEqual(expected, actual);
        Assert.AreEqual(expectedDirection, actualDirection);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void InvalidCellNumberToDirectionTest()
    {
        GameFifteen.Matrix = new string[,]
        {
            { "4","2","3","7" },
            { " ","6","11","8" },
            { "9","2","5","12" },
            { "1","10","15","13" }
        };
        GameFifteen.EmptyCellRow = 1;
        GameFifteen.EmptyCellColumn = 0;
        int cellNumber = 15;
        bool expected = false;
        bool actual;
        int actualDirection;
        int expectedDirection = -1;
        actual = GameFifteen_Accessor.CellNumberToDirection(cellNumber, out actualDirection);
        Assert.AreEqual(expected, actual);
        Assert.AreEqual(expectedDirection, actualDirection);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void CheckIfGameIsNotWonTest()
    {
        bool expected = false;
        bool actual;
        actual = GameFifteen_Accessor.CheckIfGameIsWon();
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void CheckIfGameIsNotWonWithEmptyCellInPlaceTest()
    {
        GameFifteen.Matrix = new string[,]
        {
            { "1","2","3","4" },
            { "5","6","7","8" },
            { "9","10","11","12" },
            { "13","14"," ","15" }
        };
        GameFifteen.EmptyCellRow = GameFifteen.Matrix.GetLength(0) - 1;
        GameFifteen.EmptyCellColumn = GameFifteen.Matrix.GetLength(1) - 1;
        bool expected = false;
        bool actual;
        actual = GameFifteen_Accessor.CheckIfGameIsWon();
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void CheckIfGameIsWonTest()
    {
        bool expected = true;
        bool actual;
        GameFifteen.Matrix = new string[,]
        {
            { "1","2","3","4" },
            { "5","6","7","8" },
            { "9","10","11","12" },
            { "13","14","15"," " }
        };
        GameFifteen.EmptyCellRow = GameFifteen.Matrix.GetLength(0) - 1;
        GameFifteen.EmptyCellColumn = GameFifteen.Matrix.GetLength(1) - 1;
        actual = GameFifteen_Accessor.CheckIfGameIsWon();
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void GetTopScoresFromFileTest()
    {
        string[] expected = new string[6];
        string[] actual;
        actual = GameFifteen_Accessor.GetTopScoresFromFile();
        Assert.AreEqual(expected.Length, actual.Length);
    }

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void InitializeMatrixTest()
    //{
    //    GameFifteen_Accessor.InitializeMatrix();
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void MoveCellTest()
    //{
    //    int direction = 0; // TODO: Initialize to an appropriate value
    //    GameFifteen_Accessor.MoveCell(direction);
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void NextBiggerMoveTest()
    {
        int cellNumber = 20;
        TextWriter text = new StringWriter();
        Console.SetOut(text);
        GameFifteen_Accessor.NextMove(cellNumber);
        string expected = "That cell does not exist in the matrix.\r\n";
        string actual = text.ToString();
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    public void PlayGameTest()
    {
        TextWriter output = new StringWriter();
        Console.SetOut(output);
        TextReader input = new StringReader("6\r\nexit\r\n");
        Console.SetIn(input);
        GameFifteen.Matrix = new string[,]
        {
            { "4","2","3","7" },
            { " ","6","11","8" },
            { "9","2","5","12" },
            { "1","10","15","13" }
        };
        GameFifteen.PlayGame();
        string expected = String.Format("Welcome to the game \"15\". Please try to arrange the numbers sequentially. \r\n" +
                                        "Use 'top' to view the top scoreboard, 'restart' to start a new game and 'exit'  to quit the game.\r\n" +
                                        "  ------------- \r\n" +
                                        " | {0,2} {1,2} {2,2} {3,2} |\r\n" +
                                        " | {4,2} {5,2} {6,2} {7,2} |\r\n" +
                                        " | {8,2} {9,2} {10,2} {11,2} |\r\n" +
                                        " | {12,2} {13,2} {14,2} {15,2} |\r\n" +
                                        "  ------------- \r\n" +
                                        "Enter a number to move: Illegal move!\r\n" +
                                        "Enter a number to move: Good bye!\r\n", 
                                        GameFifteen.Matrix[0,0], GameFifteen.Matrix[0,1], GameFifteen.Matrix[0,2], GameFifteen.Matrix[0,3],
                                        GameFifteen.Matrix[1,0], GameFifteen.Matrix[1,1], GameFifteen.Matrix[1,2], GameFifteen.Matrix[1,3],
                                        GameFifteen.Matrix[2,0], GameFifteen.Matrix[2,1], GameFifteen.Matrix[2,2], GameFifteen.Matrix[2,3],
                                        GameFifteen.Matrix[3,0], GameFifteen.Matrix[3,1], GameFifteen.Matrix[3,2], GameFifteen.Matrix[3,3]);
        string actual = output.ToString();
        Assert.AreEqual(expected, actual);
    }

      //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void PrintMatrixTest()
    //{
    //    GameFifteen_Accessor.PrintMatrix();
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void PrintTopScoresTest()
    {
        TextWriter output = new StringWriter();
        Console.SetOut(output);
        GameFifteen_Accessor.PrintTopScores();
        string actual = output.ToString();
        string expected = "Scoreboard:\r\n"+
        "There are no scores to display yet.\r\n";
        Assert.AreEqual(expected, actual);
    }

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void PrintWelcomeMessageTest()
    //{
    //    GameFifteen_Accessor.PrintWelcomeMessage();
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void ShuffleMatrixTest()
    {
        string[,] notExpectedMatrix = new string[,]
        {
            { "1","2","3","4" },
            { "5","6","7","8" },
            { "9","10","11","12" },
            { "13","14","15"," " }
        };
        GameFifteen_Accessor.InitializeMatrix();
        bool areEqual = true;
        GameFifteen_Accessor.ShuffleMatrix();
        for (int i = 0; i < notExpectedMatrix.GetLength(0); i++)
        {
            for (int j = 0; j < notExpectedMatrix.GetLength(1); j++)
            {
                if (notExpectedMatrix[i,j] != GameFifteen.Matrix[i,j])
                {
                    areEqual = false;
                }
            }
        }
        if (areEqual)
        {
            Assert.Fail();
        }
    }

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void TheEndTest()
    //{
    //    GameFifteen_Accessor.TheEnd();
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void UpgradeTopScoreTest()
    //{
    //    GameFifteen_Accessor.UpgradeTopScore();
    //    Assert.Inconclusive("A method that does not return a value cannot be verified.");
    //}

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void UpgradeTopScoreInFileTest()
    //{
    //    // Private Accessor for UpgradeTopScoreInFile is not found. Please rebuild the containing project or run the Publicize.exe manually.
    //    Assert.Inconclusive("Private Accessor for UpgradeTopScoreInFile is not found. Please rebuild the conta" +
    //                        "ining project or run the Publicize.exe manually.");
    //}

    //[TestMethod()]
    //[DeploymentItem("GameFifteen.exe")]
    //public void UpgradeTopScorePairsTest()
    //{
    //    string[] topScores = { null,null,null,null,null,"0. Ivan --> 12 move" };
    //    NameAndScore_Accessor[] expected = { new NameAndScore_Accessor("Ivan", 12) };
    //    NameAndScore_Accessor[] actual;
    //    actual = GameFifteen_Accessor.UpgradeTopScorePairs(topScores);
    //    Assert.AreEqual(expected.Length, actual.Length);
    //    Assert.AreEqual(expected[0], actual[0]);
    //}

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void IsCellInsideMatrixTest()
    {
        GameFifteen.EmptyCellRow = 1;
        GameFifteen.EmptyCellColumn = 0;
        int direction = 1;
        bool expected = true;
        bool actual;
        actual = GameFifteen_Accessor.IsCellInsideMatrix(direction);
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void ColumnOutsideIsCellInsideMatrixTest()
    {
        GameFifteen.EmptyCellRow = 1;
        GameFifteen.EmptyCellColumn = 0;
        int direction = 3;
        bool expected = false;
        bool actual;
        actual = GameFifteen_Accessor.IsCellInsideMatrix(direction);
        Assert.AreEqual(expected, actual);
    }

    [TestMethod()]
    [DeploymentItem("GameFifteen.exe")]
    public void RowOutsideIsCellInsideMatrixTest()
    {
        GameFifteen.EmptyCellRow = 3;
        GameFifteen.EmptyCellColumn = 0;
        int direction = 2;
        bool expected = false;
        bool actual;
        actual = GameFifteen_Accessor.IsCellInsideMatrix(direction);
        Assert.AreEqual(expected, actual);
    }
}